/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package GUI;

import Domain.GameGrid;
import Domain.Player.Player;
import Main.AppConstants;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.Serializable;
import javax.swing.*;

/**
 *
 * @author Mattis
 */
public class GameFrame extends JFrame implements Serializable{

    private int numberOfRounds;
    private GUIController guiController;
    private JPanel playerPanel;
    private JPanel boardPanel;
    private JLabel currentPlayerDisc;
    private JLabel currentPlayerLabel;
    private final Font fontPlayerName = new Font(Font.DIALOG, Font.BOLD, 12);
    private JLabel startImage = new JLabel();
    private final ImageIcon startIcon = new ImageIcon(getClass().getClassLoader().getResource(AppConstants.IMAGE_SPLASH));
    private Container content = getContentPane();

    public GameFrame(GUIController gameController) {
        this.guiController = gameController;

        javax.swing.SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                createGameFrame();
            }
        });
    }

    /**
     * Update the JLabel with the current player
     */
    public void updateCurrentPlayer(Player player) {
        currentPlayerLabel.setText(player.getName());
        currentPlayerDisc.setIcon(new DiscIcon(player.getDiscColor(), 0.3));
    }

    /**
     * Create the game frame
     */
    private void createGameFrame() {
        // Use current system look and feel:
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            SwingUtilities.updateComponentTreeUI(this);
        } catch (Exception e) {
            System.out.println(e.toString());
        }

        setIconImage(new ImageIcon(getClass().getClassLoader().getResource(AppConstants.IMAGE_APP_ICON)).getImage());

        setTitle(AppConstants.GAME_FRAME_TITLE_APP);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // Add the splash image:
        startImage.setIcon(startIcon);
        content.add(startImage, BorderLayout.CENTER);
        addButtons();

        updateGameFrame();
        setVisible(true);
        setResizable(false);
    }

    /**
     * Add new and quit buttons to the frame
     */
    private void addButtons() {
        JPanel buttonPanel = new JPanel();
        buttonPanel.setBackground(AppConstants.COLOR_PANEL_BACKGROUND);

        JButton jBtnNew = new JButton("New Game");
        jBtnNew.setBackground(AppConstants.COLOR_PANEL_BACKGROUND);
        jBtnNew.addActionListener(new NewGameListener());
        buttonPanel.add(jBtnNew);


        JButton jBtnQuit = new JButton("Quit");
        jBtnQuit.setBackground(AppConstants.COLOR_PANEL_BACKGROUND);
        jBtnQuit.addActionListener(new QuitListener());
        buttonPanel.add(jBtnQuit);
        buttonPanel.setBorder(BorderFactory.createMatteBorder(1, 0, 0, 0,
                AppConstants.COLOR_PANEL_BORDER));

        content.add(buttonPanel, BorderLayout.SOUTH);
    }

    /**
     * Add a JPanel for the current player's name to the frame
     */
    private JPanel createPlayerPanel() {
        if (playerPanel == null) {
            playerPanel = new JPanel(new FlowLayout());
            playerPanel.setBackground(AppConstants.COLOR_PANEL_BACKGROUND);

            // Current player:
            JLabel curPlayerLabel = new JLabel("Current player:");
            curPlayerLabel.setForeground(AppConstants.COLOR_PANEL_FOREGROUND);
            playerPanel.add(curPlayerLabel);

            // Player's disc:
            currentPlayerDisc = new JLabel();
            playerPanel.add(currentPlayerDisc);

            // Player's name:
            currentPlayerLabel = new JLabel();
            currentPlayerLabel.setFont(fontPlayerName);
            currentPlayerLabel.setForeground(AppConstants.COLOR_PANEL_FOREGROUND);
            playerPanel.add(currentPlayerLabel);

            playerPanel.setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0,
                    AppConstants.COLOR_PANEL_BORDER));
        }
        return playerPanel;
    }

    /**
     * Adds the game board to the frame
     */
    private JPanel getGameBoard() {
        int boardWidth = GameGrid.GRID_COLUMNS * 80;
        int boardHeight = GameGrid.GRID_ROWS * 80 - (boardPanel != null ? 10 : 0);

        // Remove the old boardPanel:
        if (boardPanel != null) {
            remove(boardPanel);
        }

        // Get the game board and set its dimensions:
        boardPanel = guiController.getGameBoardPanel();
        boardPanel.setSize(new Dimension(boardWidth, boardHeight));
        boardPanel.setPreferredSize(new Dimension(boardWidth, boardHeight));

        return boardPanel;
    }

    /**
     * Updates the game frame
     */
    public void updateGameFrame() {
        pack();
        setLocationRelativeTo(null);
        repaint();
    }

    /**
     * Adds a menu bar with options for changing the AI of a computer controlled
     * player.
     */
    private JMenuBar GameFrameMenuBar() {
        JMenuBar jmnBar = new JMenuBar();
        JMenu menuAI = new JMenu("AI Settings");

        JMenuItem jmniAI = new JMenuItem("Change Computer AI");
        jmniAI.addActionListener(new AISettingsListener());
        menuAI.add(jmniAI);

        JMenuItem jmniAID = new JMenuItem("Enter Debug");
        jmniAID.addActionListener(new DebugListener());
        menuAI.add(jmniAID);



        JMenuItem jmniSetBoard = new JMenuItem("SetBoard");
        jmniSetBoard.addActionListener(new SetBoardListener());
        menuAI.add(jmniSetBoard);

        jmnBar.add(menuAI);
        return jmnBar;
    }

    /**
     * Creates a new game board
     */
    private void newGameBoard() {
        SetupGameDialog setupGameDialog = new SetupGameDialog(
                guiController.getPlayer(1), guiController.getPlayer(2));
        Player player1 = setupGameDialog.getPlayer(1);
        Player player2 = setupGameDialog.getPlayer(2);

        if (player1 != null && player2 != null) {
            // Remove start image:
            if (startImage != null) {
                remove(startImage);
            }
            guiController.resetGame();
            guiController.addPlayers(player1, player2);

            // Add player panel:
            content.add(createPlayerPanel(), BorderLayout.NORTH);

            // Add game board:
            boardPanel = getGameBoard();
            content.add(boardPanel, BorderLayout.CENTER);

            // Update the game frame:
            updateGameFrame();
            // Start the game:
            guiController.startGame();
        }
    }

    /**
     * Creates a new game board
     */
    private void customizedGameBoard() {
        SetupGameDialog setupGameDialog = new SetupGameDialog(
                guiController.getPlayer(1), guiController.getPlayer(2));
        Player player1 = setupGameDialog.getPlayer(1);
        Player player2 = setupGameDialog.getPlayer(2);

        if (player1 != null && player2 != null) {
            // Remove start image:
            if (startImage != null) {
                remove(startImage);
            }

            guiController.resetGameBoard();
            guiController.addPlayers(player1, player2);

            // Add player panel:
            content.add(createPlayerPanel(), BorderLayout.NORTH);

            // Add game board:
            boardPanel = getGameBoard();
            content.add(boardPanel, BorderLayout.CENTER);

            // Update the game frame:
            guiController.getGameBoardPanel().updateGameBoard();
            updateGameFrame();

            // Start the game:
            guiController.startGame();
        }
    }

    /**
     * Button listener: New Game
     */
    private class NewGameListener implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {
            setJMenuBar(GameFrameMenuBar());
            newGameBoard();
        }
    }

    /**
     * Button listener: Quit
     */
    private class QuitListener implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {
            guiController.quitGame();
            for (Frame frameEle : Frame.getFrames()) {
                frameEle.dispose();
            }
            System.exit(0);
        }
    }

    /**
     * Button listener: AI settings
     */
    private class AISettingsListener implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent ae) {
            //new SetupAIDialog(guiController.getPlayer(0), guiController.getPlayer(1));
        }
    }

    /**
     * Button listener: Debug
     */
    private class DebugListener implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent ae) {
            System.out.println("entering debug");
            guiController.setDebug(true);
        }
    }

    /**
     * Button listener: SetBoard
     */
    private class SetBoardListener implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent ae) {
            System.out.println("setting board");
            guiController.presentSetBoardDialog();
        }
    }
    
    public int getNumberOfRounds(){
        return this.numberOfRounds;
    }
}/**/